package scales.xml.parser.strategies
import scales.xml._
import scales.utils.collection.Tree
import scales.utils.valueOf
import scales.xml.impl.{NotFromParser, FromParser}
import impl.ElemKey
class ElemToken(implicit ver : XmlVersion, fromParser : FromParser) extends QNameToken {
val ekey = new ElemKey()
val ef = (key : ElemKey) => Elem(key.name, key.attributes, key.namespaces)
}
trait ElemTokenF {
def createToken(implicit ver : XmlVersion, fromParser : FromParser) = new ElemToken()
}
trait ElemQNameOptimisationT[Token <: ElemToken] extends QNameOptimisationT[Token] {
import java.util.concurrent.ConcurrentHashMap
val ecache = new ConcurrentHashMap[ ElemKey, Elem ]
val cacheAll = false
def elemValue(key : ElemKey)( newT : ElemKey => Elem ) : Elem = {
var value = ecache.get(key)
if (value == null) {
value = newT(key)
val res = ecache.putIfAbsent(key.copy, value)
value = if (res == null) value else res
}
value
}
override def elem( name : QName, attributes : Attributes, namespaces : Map[String, String], token : Token) : Elem = {
val et = token
import et._
if (cacheAll ||
((attributes eq emptyAttributes) &&
(namespaces eq emptyNamespaces))
)
elemValue(ekey.set(name, attributes, namespaces, qkey.lastHash) )( ef )
else Elem(name, attributes, namespaces)(token.fromParser)
}
}
trait FullMemoryOptimisationT[Token <: ElemToken] extends ElemQNameOptimisationT[Token] {
override val cacheAll = true
}
trait ElemOptimisationT[Token <: OptimisationToken] extends MemoryOptimisationStrategy[Token] {
import java.util.concurrent.ConcurrentHashMap
val cache = new ConcurrentHashMap[ Elem, Elem ]
override def elem( name : QName, attributes : Attributes, namespaces : Map[String, String], token : Token) : Elem = {
import token._
valueOf(Elem(name, attributes, namespaces), cache) (Elem(name, attributes, namespaces))
}
}
object ElemMemoryOptimisation extends PathOptimisationStrategy[ElemToken] with ElemOptimisationT[ElemToken] with ElemTokenF
object HighMemoryOptimisation extends PathOptimisationStrategy[ElemToken] with ElemOptimisationT[ElemToken] with QNameOptimisationT[ElemToken] with ElemTokenF
trait TextNodeJoiner[Token <: OptimisationToken] extends TreeOptimisation[Token] {
import ScalesXml.xmlCBF
def newTree( elem : Elem, children : XmlChildren, token : Token ) : XmlTree =
Tree(elem, joinTextNodes(children))
}